package com.garbuz.svnadmin.model;

import com.garbuz.svnadmin.SvnModelError;
import com.garbuz.svnadmin.data.Group;
import com.garbuz.svnadmin.data.Permission;
import com.garbuz.svnadmin.data.Repo;
import com.garbuz.svnadmin.data.User;

import java.util.ArrayList;
import java.util.List;

public class SvnModel
{

	private List<Repo> repos = new ArrayList<Repo>();
	private List<User> users = new ArrayList<User>();
	private List<Group> groups = new ArrayList<Group>();

	public SvnModel()
	{
		super();
	}

	public void removeGroup(String groupName) throws Exception
	{
		Group group = getGroup(groupName);
		groups.remove(group);
		for (User user: users)
		{
			user.groupNames.remove(groupName);
		}
	}
	
	public void addGroup(String name) throws Exception
	{
		if (groupExists(name))
			throw new SvnModelError("Such group already exists.");

		groups.add(new Group(name));
	}

	public boolean groupExists(String name)
	{
		return getGroup(name) != null;
	}

	public Group getGroup(String name)
	{
		for (Group group : groups)
		{
			if (group.name.equals(name))
				return group;
		}
		return null;
	}

	public void addUser(String name) throws Exception
	{
		if (userExists(name))
			throw new SvnModelError("Such user already exists.");

		users.add(new User(name));
	}

	public void removeUser(String name)
	{
		User user = getUser(name);
		
		if (user == null)
			return;
		
		users.remove(user);
	}

	public boolean userExists(String name)
	{
		return getUser(name) != null;
	}

	public User getUser(String name)
	{
		for (User user : users)
		{
			if (user.name.equals(name))
				return user;
		}
		return null;
	}

	public Repo getRepo(String repoName)
	{
		for (Repo repo : repos)
		{
			if (repo.name.equals(repoName))
				return repo;
		}
		return null;
	}

	public List<User> getUsersInGroup(String groupName)
	{
		List<User> result = new ArrayList<User>();
		for (User user: users)
		{
			if (user.groupNames.contains(groupName))
				result.add(user);
		}
		return result;
	}

	public void setGroupUsers(String groupName, List<String> userNames) throws SvnModelError
	{
		Group group = getGroup(groupName);

		if (group == null)
			throw new SvnModelError("Group not found");

		for (User user : users)
		{
			if (userNames.contains(user.name))
			{
				if (!user.groupNames.contains(groupName))
					user.groupNames.add(groupName);
			}
			else
			{
				user.groupNames.remove(groupName);
			}
		}
	}

	public void setUserGroups(String userName, List<String> groupNames) throws SvnModelError
	{
		User user = getUser(userName);

		if (user == null)
			throw new SvnModelError("User not found");

		user.groupNames = groupNames;
	}
	
	public List<Permission> getPossiblePermissions()
	{
		ArrayList<Permission> permissions = new ArrayList<Permission>();

		permissions.add(new Permission(new Group(Group.ALL_NAME)));

		for (Group group:groups)
		{
			permissions.add(new Permission(group));
		}

		for (User user:users)
		{
			permissions.add(new Permission(user));
		}
		
		return permissions;
	}

	public List<Repo> getRepos()
	{
		return repos;
	}

	public List<User> getUsers()
	{
		return users;
	}

	public List<Group> getGroups()
	{
		return groups;
	}

	public void applyPermissions(String name, List<Permission> permissions) throws SvnModelError
	{
		Repo repo = getRepo(name);
		
		if (repo == null)
			throw new SvnModelError("Repository not found");

		repo.permissions.clear();
		for (Permission permission : permissions)
		{
			repo.permissions.add(permission);
		}
	}
}
